#include "sdb.h"

#define NR_WP 32

typedef struct watchpoint {
  int NO;
  struct watchpoint *next;
  char expr[65536];
  word_t value;

  /* TODO: Add more members if necessary */

} WP;

static WP wp_pool[NR_WP] = {};
static WP *head = NULL, *free_ = NULL;
void init_wp_pool() {
  int i;
  for (i = 0; i < NR_WP; i ++) {
    wp_pool[i].NO = i;
    wp_pool[i].next = (i == NR_WP - 1 ? NULL : &wp_pool[i + 1]);
  }

  head = NULL;
  free_ = wp_pool;
}

/* TODO: Implement the functionality of watchpoint */


void free_wp (int NO){
WP *p = head;
if (head == NULL){
	printf("Head is NULL\n");
	assert(0);
}
else if(p->NO == NO) //head is special
{
	head=head->next;
	p->value = 0;
	p->next = free_;
	free_ = p;
	printf("NO:%d has been deleted\n",NO);
	return;
}
else{
WP *q = head;
p = p -> next;
while(p!= NULL){
	if(p->NO == NO){
		q->next = p->next;
		p->value = 0;
		p->next = free_;
		free_ = p;
		printf("NO:%d has been deleted\n",NO);
		return;
	}
	else {
		p = p->next;
		q = q->next;
	}
	}
}

printf("delete fault\n");
return ;
}

void print_wp(){
WP *p = head;
if (p == NULL){
	printf("Head is NULL\n");
	return;
}
else{
	while(p != NULL){
		printf("No:%d %s 0x%016lx\n",p->NO, p->expr, p->value);
		p = p->next;
	}
	return;
}
return;
}

bool check_wp(){
WP *p = head;
bool success = true;
bool change = false;
word_t value;
if (p == NULL){
//	printf("Head is NULL\n");
	return change;
}
else{
	while(p != NULL){
		value = expr(p->expr,&success);
		if(value != p->value){
			printf("No:%d %s has changed from 0x%08lx to 0x%08lx now\n",p->NO, p->expr, p->value,value);
			p->value = value;
			change = true;
		}	
		p = p->next;
	}
	return change;
}

}

void new_wp(char *expr, word_t value){

if (free_ == NULL){
	printf("Free is NULL\n");
	assert(0);
}

WP *newwp = NULL;

newwp = free_;

free_ = free_->next;

newwp->value = value;
//new->expr = expr;
strcpy(newwp->expr,expr);
//printf("doing here5\n");

newwp->next = NULL;


if (head == NULL){
	head=newwp;
//	printf("head begin\n");
	}
else{
	newwp->next = head;
	head = newwp;
}
printf("A new watch %d point is added,with value: 0x%016lx\n",newwp->NO,newwp->value);
return;
}
